package net.cyndeline.rldungeon.dgs.strategy.pointlessArea

import scalax.collection.immutable.Graph
import scala.util.Random
import net.cyndeline.rldungeon.dgs.graph.{DGSFunctionality, Room}
import scalax.collection.GraphEdge.UnDiEdge
import scalax.collection.GraphPredef.OuterEdge
import net.cyndeline.rldungeon.dgs.{ActivatorResponderAmountEstimator, EdgeCopyFactory, RewardProcessor, ActivatorResponderProcessor}
import scala.reflect.runtime.universe._
import scala.reflect._
import net.cyndeline.rldungeon.dgs.strategy.help.{CollapsedEdge, CollapsedNode}

/**
 * Reduces the amount of pointless areas in a game map (areas that doesn't need to be visited in order to
 * complete the level).
 */
trait PointlessAreaReductionStrategy {

  /**
   * Produces a graph representation of a map.
   *
   * @param initialGraph The graph that the productions initially will be applied to.
   * @param cycleCollapsedGraph Cycle-collapsed version of the initial graph, where every vertex is represented by
   *                            a collapsed node.
   * @param start Start vertex in the initial graph.
   * @param goal Stop vertex in the initial graph.
   * @param random Random object used to select responder amounts.
   * @param activatorResponderProcessor Modifies rooms and corridors by adding responders and activators to them.
   * @param rewardProcessor Modifies rooms by adding rewards to them.
   * @param edgeFactory Creates new edges from a pair of vertices.
   * @param responderAmount Responsible for computing the amount of responders that should be placed on a map.
   * @return the finished map graph if one was possible to produce according to the strategy, otherwise None.
   */
  def apply[VType <: Room[VType]: ClassTag : TypeTag, EType[X] <: UnDiEdge[X] with DGSFunctionality[X, EType] with OuterEdge[X, EType]]
    (initialGraph: Graph[VType, EType],
     cycleCollapsedGraph: Graph[CollapsedNode[VType], CollapsedEdge[VType]#Inner],
     start: VType,
     goal: VType,
     random: Random,
     activatorResponderProcessor: ActivatorResponderProcessor[VType, EType],
     rewardProcessor: RewardProcessor[VType, EType],
     edgeFactory: EdgeCopyFactory[VType, EType],
     responderAmount: ActivatorResponderAmountEstimator[VType, EType]): Option[Graph[VType, EType]]
}
